﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

using Scheduling.Models;
using Scheduling.Models.Helpers;
using Scheduling.Models.Interfaces;
using Scheduling.Models.Extensions;

namespace Scheduling.Controllers
{
    public class UserController : BaseController
    {
        
        public ActionResult List()
        {
            var userLoader = IoC.Resolve<IUserLoader>();
            var users = userLoader.GetUsers();
            return View(users);
        }
        [Restrict(Roles = "Bookers")]
        public ActionResult Show(String id)
        {
            var userLoader = IoC.Resolve<IUserLoader>();
            if (!userLoader.UserExists(id))
                FileNotFound();

            var user = userLoader.GetUser(id);
            return View(user);
        }

        [HttpGet]
        public ActionResult Login()
        {
            return View();
        }



        [HttpGet]
        public ActionResult Add()
        {

            return View();
        }

        [HttpPost]
        [Restrict(Roles = "Administrators")]
        public ActionResult Add(FormCollection form)
        {
            var userLoader = IoC.Resolve<IUserLoader>();

            foreach (string key in form.Keys)
                ViewData[key] = form.Get(key);

            string ErrorMessage = UserHelper.ValidateUserInput(ViewData["inId"].ToString(), ViewData["inGroup"].ToString(), ViewData["inDepartment"].ToString(), ViewData["inFirstName"].ToString(), ViewData["inLastName"].ToString(), ViewData["inPasswd1"].ToString(), ViewData["inPasswd2"].ToString(), ViewData["inEmail"].ToString(), ViewData["inPhone"].ToString());
            if (userLoader.UserExists(ViewData["inId"].ToString()))
                return View((object)"Initials already used");

            if (ErrorMessage != null)
                return View((object)ErrorMessage);


            userLoader.InsertUser(UserHelper.CreateUserFromStrings(ViewData["inId"].ToString(), ViewData["inGroup"].ToString(), ViewData["inDepartment"].ToString(), ViewData["inFirstName"].ToString(), ViewData["inLastName"].ToString(), ViewData["inPasswd1"].ToString().Hash(), ViewData["inEmail"].ToString(), ViewData["inPhone"].ToString()));
            return RedirectToAction("List");
        }

        [HttpGet]
        [Restrict(Roles = "Administrators")]
        public ActionResult Edit(string Id)
        {
            var userLoader = IoC.Resolve<IUserLoader>();
            User editedUser = userLoader.GetUser(Id);

            if (editedUser == null)
                FileNotFound();

            ViewData["inId"] = editedUser.ID;
            ViewData["inFirstName"] = editedUser.FirstName;
            ViewData["inLastName"] = editedUser.LastName;
            ViewData["inGroup"] = editedUser.UserGroup.Name;
            ViewData["inDepartment"] = editedUser.Department.Name;
            ViewData["inEmail"] = editedUser.Email;
            ViewData["inPhone"] = editedUser.Phone;
            return View();
        }

        [HttpPost]
        [Restrict(Roles = "Administrators")]
        public ActionResult Edit(FormCollection form)
        {
            foreach (string key in form.Keys)
                ViewData[key] = form.Get(key);

            var userLoader = IoC.Resolve<IUserLoader>();
            User editedUser = userLoader.GetUser(ViewData["inId"].ToString());

            string ErrorMessage = UserHelper.ValidateUserInput(ViewData["inId"].ToString(), ViewData["inGroup"].ToString(), ViewData["inDepartment"].ToString(), ViewData["inFirstName"].ToString(), ViewData["inLastName"].ToString(), editedUser.Password, editedUser.Password, ViewData["inEmail"].ToString(), ViewData["inPhone"].ToString());
            if (ErrorMessage != null)
                return View((object)ErrorMessage);
            User tempUser = UserHelper.CreateUserFromStrings(ViewData["inId"].ToString(), ViewData["inGroup"].ToString(), ViewData["inDepartment"].ToString(), ViewData["inFirstName"].ToString(), ViewData["inLastName"].ToString(), editedUser.Password, ViewData["inEmail"].ToString(), ViewData["inPhone"].ToString());
            userLoader.EditUser(tempUser);
            return RedirectToAction("Show", editedUser);
        }

        [HttpGet]
        [Restrict(Roles = "Administrators")]
        public ActionResult Remove(String Id)
        {
            var userLoader = IoC.Resolve<IUserLoader>();

            if (userLoader.UserExists(Id))
                userLoader.DeleteUser(Id);
            else
                FileNotFound();

            return RedirectToAction("List");
        }

        public void Add(string inUsername, string inPassword)
        {
        }

        [HttpPost]
        public ActionResult Login(string inUsername, string inPassword)
        {
            var user = UserHelper.Authenticate(inUsername, inPassword);
            if (user != null)
            {
                UserHelper.LoadIntoSession(user);
                return RedirectToAction("Index", new { Controller = "Home" });
            }
            else
            {
                ViewData["message"] = "Invalid Username and/or Password. ";
                return View();
            }
        }

        [HttpGet]
        public ActionResult Logout()
        {
            UserHelper.UnloadUserFromSession();
            return RedirectToAction("Index", new { Controller = "Home" });
        }

        [HttpGet]
        public ActionResult ResetPassword(string Token, string UserID)
        {

            var userLoader = IoC.Resolve<IUserLoader>();
            if (UserHelper.VerifyResetToken(Token, UserID) && userLoader.UserExists(UserID))
            {
                return View(userLoader.GetUser(UserID));
            }
            else
            {
                return RedirectToAction("Index", new { Controller = "Home" });
            }
        }

        [HttpPost]
        public ActionResult ResetPassword(string inUserToEdit, string inNewPasswd, string inNewPasswdRepeat)
        {
            var userLoader = IoC.Resolve<IUserLoader>();

            if (userLoader.UserExists(inUserToEdit) && inNewPasswd != "" && inNewPasswd != null && inNewPasswd == inNewPasswdRepeat)
            {
                UserHelper.UpdateUserPassword(inNewPasswd, inUserToEdit);
                return RedirectToAction("Index", new { Controller = "Home" });
            }
            else if (userLoader.UserExists(inUserToEdit) && inNewPasswd != "" && inNewPasswd != null && inNewPasswd != inNewPasswdRepeat)
            {
                ViewData["message"] = "Passwords do not match";
                return View(userLoader.GetUser(inUserToEdit));
            }
            else
            {
                return RedirectToAction("Index", new { Controller = "Home" });
            }

        }

        [HttpGet]
        public ActionResult UpdatePasswordForUser(string inUserID)
        {
            var userLoader = IoC.Resolve<IUserLoader>();
            if (!userLoader.UserExists(inUserID))
            {
                ViewData["message"] = "Invalid user specified.";
                return View();
            }
            else
            {
                var user = userLoader.GetUser(inUserID);
                return View(user);
            }
        }

        [HttpPost]
        public ActionResult UpdatePasswordForUser(string inUserID, string inOldPasswd, string inNewPasswd, string inNewPasswdRepeat)
        {
            var userLoader = IoC.Resolve<IUserLoader>();
            if (!userLoader.UserExists(inUserID))
            {
                ViewData["message"] = "Invalid user specified.";
                return View();
            }
            else
            {
                var user = userLoader.GetUser(inUserID);

                if (inOldPasswd.Hash() == user.Password)
                {
                    if (inNewPasswd == inNewPasswdRepeat)
                    {
                        ViewData["message"] = "Updated successfully";
                        UserHelper.UpdateUserPassword(inNewPasswd, inUserID);
                    }
                    else
                    {
                        ViewData["message"] = "Passwords do not match";
                    }
                }
                else
                {
                    ViewData["message"] = "Old password is incorrect";
                }
                return View();
            }
        }

        [HttpGet]
        public ActionResult UpdatePassword()
        {
            var currentUser = UserHelper.GetAuthenticatedUser();
            return View(currentUser);
        }

        [HttpPost]
        public ActionResult UpdatePassword(string inOldPasswd, string inNewPasswd, string inNewPasswdRepeat)
        {
            var currentUser = UserHelper.GetAuthenticatedUser();
            if (inOldPasswd.Hash() == currentUser.Password)
            {
                if (inNewPasswd == inNewPasswdRepeat)
                {
                    ViewData["message"] = "Updated successfully";
                    UserHelper.UpdateUserPassword(inNewPasswd);
                }
                else
                {
                    ViewData["message"] = "Passwords do not match";
                }
            }
            else
            {
                ViewData["message"] = "Old password is incorrect";
            }
            return View();
        }

        [HttpGet]
        public ActionResult RequestPasswordReset()
        {
            return View();
        }

        [HttpPost]
        public ActionResult RequestPasswordReset(string inUserID, string inEmail)
        {

            if (UserHelper.VerifyUserEmail(inEmail, inUserID))
            {
                UserHelper.SendResetPasswordEmail(inUserID);
                ViewData["message"] = "Email sent, check your inbox for further instructions.";
            }
            else
            {
                ViewData["message"] = "You've entered the wrong initials/email or your user does not exist.";
            }
            return View();
        }

        [HttpGet]
        [Restrict(Roles = "Administrators")]
        public ActionResult SetUserPassword(string UserID)
        {

            var userLoader = IoC.Resolve<IUserLoader>();
            if (userLoader.UserExists(UserID))
            {
                ViewData["user"] = UserID;
                return View();
            }
            else
            {
               return Redirect("List");
            }
        }
        [HttpPost]
        [Restrict(Roles = "Administrators")]
        public ActionResult SetUserPassword(string UserID,string NewPassWord,string NewPassWordConfirm)
        {
            
                var userLoader = IoC.Resolve<IUserLoader>();
                if (NewPassWord == NewPassWordConfirm && userLoader.UserExists(UserID))
                {
                    User user = userLoader.GetUser(UserID);
                    user.Password=NewPassWord.Hash();
                    userLoader.EditUser(user);
                    return Redirect("List");
                }
                else
                {
                    ViewData["message"] = "Passwords do not match";
                    return View();
                }
            
 
        }
    }
}
